#include <iostream>
#include <thread>
#include <chrono>
#include <map>
#include <unordered_map>
#include <iomanip>
#include <csignal>

#include "shm_utils.h"
#include "def.h"


// 本地维护 OrderBook（只保留 ORDERBOOK_DEPTH 档）
struct OrderBook {
    std::map<long long, double> asks;                      // 卖盘（升序）
    std::map<long long, double, std::greater<long long>> bids; // 买盘（降序）
    int depth; // 保存深度

    OrderBook(int d) : depth(d) {}

    void trim() {
        // 剔除多余档位
        int i = 0;
        for (auto it = asks.begin(); it != asks.end();) {
            if (i++ >= depth)
                it = asks.erase(it);
            else
                ++it;
        }
        i = 0;
        for (auto it = bids.begin(); it != bids.end();) {
            if (i++ >= depth)
                it = bids.erase(it);
            else
                ++it;
        }
    }

    void print() const {
        std::cout << "--- Asks (" << asks.size() << ") ---\n";
        int i = 0;
        for (auto it = asks.begin(); it != asks.end(); ++it, ++i)
            std::cout << "  " << i << ": price=" << it->first << " size=" << it->second << "\n";

        std::cout << "--- Bids (" << bids.size() << ") ---\n";
        i = 0;
        for (auto it = bids.begin(); it != bids.end(); ++it, ++i)
            std::cout << "  " << i << ": price=" << it->first << " size=" << it->second << "\n";
    }
};

// exchange -> (symbol -> OrderBook*)
std::unordered_map<uint8_t, std::unordered_map<std::string, OrderBook*>> exchangeBooks;
int ORDERBOOK_DEPTH = 5;

// 反向映射：market_id -> symbol
static std::unordered_map<uint32_t, std::string> buildMarketIdToSymbol() {
    std::unordered_map<uint32_t, std::string> m;
    for (const auto& kv : SymbolEnumMap) {
        m[static_cast<uint32_t>(kv.second)] = kv.first;
    }
    return m;
}

// 反向映射：exchange_id -> name
static std::unordered_map<uint8_t, std::string> buildExchangeIdToName() {
    std::unordered_map<uint8_t, std::string> m;
    for (const auto& kv : ExchangeEnumMap) {
        m[static_cast<uint8_t>(kv.second)] = kv.first;
    }
    return m;
}

static const std::unordered_map<uint32_t, std::string> MARKET_ID_TO_SYMBOL = buildMarketIdToSymbol();
static const std::unordered_map<uint8_t, std::string> EXCHANGE_ID_TO_NAME = buildExchangeIdToName();

void signal_handler(int signum) {
    std::cout << "\n\n⚡ 捕获 Ctrl+C, 打印全部前 " << ORDERBOOK_DEPTH << " 档 OrderBook:\n";
    for (const auto& exPair : exchangeBooks) {
        auto exId = exPair.first;
        auto exNameIt = EXCHANGE_ID_TO_NAME.find(exId);
        const std::string exName = (exNameIt != EXCHANGE_ID_TO_NAME.end()) ? exNameIt->second : ("EX#" + std::to_string(exId));
        std::cout << "Exchange: " << exName << "\n";

        for (const auto& symPair : exPair.second) {
            const std::string& symbol = symPair.first;
            OrderBook* bookPtr = symPair.second;
            if (!bookPtr) continue;
            std::cout << "Symbol: " << symbol << "\n";
            bookPtr->trim();
            bookPtr->print();
            std::cout << "--------------------\n";
        }
        std::cout << "====================\n";
    }
    exit(0);
}

int main() {
    try {
        signal(SIGINT, signal_handler); // 捕获 Ctrl+C

        auto* shm_ptr = link_shm_read_only<MARKETStruct>("_v1");
        if (!shm_ptr) {
            std::cerr << "❌ 无法连接共享内存 _v1" << std::endl;
            return 1;
        }

        size_t last_index = 0;
        std::cout << "🚀 启动共享内存读取器" << std::endl;

        while (true) {
            size_t write_index = shm_ptr->priceLevelShm.next_write.load();

            while (last_index < write_index) {
                const auto& pls = shm_ptr->priceLevelShm[last_index];

                // 解析 exchange 与 symbol
                const uint8_t exchangeId = pls.exchange;
                const uint32_t marketId = pls.market_id;
                auto symIt = MARKET_ID_TO_SYMBOL.find(marketId);
                const std::string symbol = (symIt != MARKET_ID_TO_SYMBOL.end()) ? symIt->second : ("MID#" + std::to_string(marketId));

                // 获取或创建 OrderBook（按 exchange->symbol）
                OrderBook*& bookPtr = exchangeBooks[exchangeId][symbol];
                if (!bookPtr)
                    bookPtr = new OrderBook(ORDERBOOK_DEPTH);
                OrderBook& book = *bookPtr;

                if (pls.order_side == OrderSideEnum::BID) {
                    if (pls.pl.size == 0)
                        book.bids.erase(pls.pl.price);
                    else
                        book.bids[pls.pl.price] = pls.pl.size;
                } else {
                    if (pls.pl.size == 0)
                        book.asks.erase(pls.pl.price);
                    else
                        book.asks[pls.pl.price] = pls.pl.size;
                }
                book.trim();
                ++last_index;
            }
        }
    } catch (const std::exception& e) {
        std::cerr << "❌ Error: " << e.what() << std::endl;
    }
}
